﻿// ----------------------------------------------------------------------------------------
// Author:                    Joaquín López y Magally Vargas
// Company:                   Albalia Interactiva S.L
// Assembly version:          1.0.0.0
// Date:                      10/02/2009
// Time:                      12:11
// Solution Name:             FacturaeAdd-in
// Solution Filename:         FacturaeAdd-in.sln
// Solution FullFilename:     C:\Ribbon_Facturae\FacturaeAdd-in.sln
// Project Name:              FacturaeAdd-in
// Project Filename:          FacturaeAdd-in.csproj
// Project FullFilename:      C:\Ribbon_Facturae\FacturaeAdd-in\FacturaeAdd-in.csproj
// Project Item Name:         ThisAddIn.cs
// Project Item Filename:     ThisAddIn.cs
// Project Item FullFilename: C:\Ribbon_Facturae\FacturaeAdd-in\ThisAddIn.cs
// Project Item Kind:         Código
// Purpose:                   funcionalidad de la aplicación de Office word para el manejo de facturae
//Copyright © 2008 - 2009 Albalia Interactiva S.L. Reservados todos los derechos.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using System.Xml;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Word;
using FacturaeAdd_in.XmlMngFiles;
using System.Xml.XPath;
using FacturaeAdd_in.FacturaeFiles;
using System.Xml.Serialization;
using Xades;
using System.IO;
using System.IO.Packaging;
using System.Globalization;

namespace FacturaeAdd_in
{
    /// <summary>
    /// Clase que representa la aplicacion addin
    /// </summary>
    public partial class ThisAddIn
    {
        #region "Fields"

        /// <summary>
        /// Variable que referencia al taskpane
        /// </summary>
        Microsoft.Office.Tools.CustomTaskPane taskPane;

        /// <summary>
        /// Atributo de tipo string que referencia al ID del custompart
        /// </summary>
        [CachedAttribute()]
        public string facturaeXMLPartID = string.Empty;

        /// <summary>
        /// Variable que referencia al custompart
        /// </summary>
        private Office.CustomXMLPart facturaXMLPart;

        /// <summary>
        /// 
        /// </summary>
        [CachedAttribute()]
        public string configXMLPartID = string.Empty;

        /// <summary>
        /// Variable con el espacio de nombres de los esquemas xml
        /// </summary>
        private const string prefix = "xmlns:xsd='http://www.w3.org/2001/XMLSchema'";

        /// <summary>
        /// Variable de tipo string con el valor de la variable de entorno
        /// </summary>
        public string EnvironmentVariable = "";

        /// <summary>
        /// Variable que referencia al documento
        /// </summary>
        Word.Document document;

        /// <summary>
        /// Variable que referencia al parser que se encarga de manejar los archivos de gestion de facturas
        /// </summary>
        XmlFileMngParser parser;

        /// <summary>
        /// Variable de tipo char[] que contiene los caracteres que se deben elimiar cuando se cogen los valores
        /// de los controles de la plantilla.
        /// </summary>
        char[] x = { '\r', '\a', '\n' };

        /// <summary>
        /// Variables de tipo int que refencian a una numeración específica de las tablas de una planilla facturae
        /// Si alguna de estas referencias falla, significa qe no estamos trabajando con una plantilla válida.
        /// </summary>
        public int t1, t2, t3, t4, t5, t6, t7;

        /// <summary>
        /// Variable que referencia al ribbon
        /// </summary>
        Ribbon1 ribbon;

        /// <summary>
        /// Variable de tipo ConfiData, que una vez instanciada no se elimina hasta que se cierra la aplicación
        /// que contiene la configuración predeterminada por el usuario.De esta manera no se consulta constantemente
        /// el archivo xml que almacena esta configuración.
        /// </summary>
        ConfigData configuration;

        /// <summary>
        /// Variable utilizada para cambiar la cultura.
        /// </summary>
        public CultureInfo InvoiceCulture;

        /// <summary>
        /// Variable que referencia al taskpane.
        /// </summary>
        InvoiceTaskPane invoicetaskpane;

        /// <summary>
        /// idioma de la aplicacion
        /// </summary>
        String language;

        #endregion

        #region propiedades

        /// <summary>
        /// Propiedad de tipo string que contine el valor del directorio de las plantillas
        /// </summary>
        public string TemplatesDirectories { get; set; }
        
        #endregion

        #region "Private Methods"

        /// <summary>
        /// Método que se ejecura al iniciar la aplicación, inicializando todo los datos necesarios
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            InvoiceCulture = CultureInfo.InstalledUICulture;

            //EnvironmentVariable = System.Environment.GetEnvironmentVariable("ProgramFiles");
            EnvironmentVariable = System.Environment.GetEnvironmentVariable("APPDATA");
            parser = new XmlFileMngParser();
            CultureInfo cInfo = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
             language = cInfo.Name;
            TemplatesDirectories = string.Concat(language, @"\");
        }

        /// <summary>
        /// Método que se ejecura al cerrar la aplicación
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {

        }

        #endregion

        #region public Methods

        /// <summary>
        /// Método que leer un archivo y devuelve su contenido como un string
        /// </summary>
        /// <param name="pathSignedInvoice">Parámetro de tipo string con el path del archivo</param>
        /// <returns>Un string con el contenido del archivo</returns>
        public  string GetXmlFromResource(string pathSignedInvoice)
        {

            using (System.IO.StreamReader resourceReader = new System.IO.StreamReader(pathSignedInvoice))
            {
                if (resourceReader != null)
                {
                    return resourceReader.ReadToEnd();
                }
            }

            return null;
        }

        /// <summary>
        /// Método que añade la facturae como tal como un custompart al documento.
        /// </summary>
        /// <param name="xmlData">Contenido del custompart</param>
        /// <param name="document">Documento al que se le añade</param>
        public  void AddCustomXmlPart(string xmlData, Word.Document document)
        {
            
            if (xmlData != null)
            {
                string id = GetControlValue(ControlList.Tag.customPartId);
                if (id != null)
                    facturaeXMLPartID = id;

                facturaXMLPart = document.CustomXMLParts.SelectByID(facturaeXMLPartID);
               
                if (facturaXMLPart == null)
                {
                    facturaXMLPart = document.CustomXMLParts.Add(xmlData, missing);
                    facturaeXMLPartID = facturaXMLPart.Id;
                    getControlByTag(ControlList.Tag.customPartId).LockContents = false;
                    setControlValue(ControlList.Tag.customPartId, facturaeXMLPartID);
                    getControlByTag(ControlList.Tag.customPartId).LockContents = true;
                }


            }
        }
              
        /// <summary>
        /// Método que extrae una facturae de un docx.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="notify"></param>
        public void extraerfacturae(string path , bool notify)
        {      

            if (!string.IsNullOrEmpty(path))
            {
                Office.CustomXMLPart customPartReceived;
                try
                {
                    string customPartID = GetControlValue(ControlList.Tag.customPartId);

                  

                        customPartReceived = this.Application.ActiveDocument.CustomXMLParts.SelectByID(customPartID);

                        if (customPartReceived != null)
                        {
                            XmlDocument doc = new XmlDocument();
                            doc.PreserveWhitespace = true;
                            doc.LoadXml(customPartReceived.DocumentElement.XML);
                            doc.Save(path);

                            if (notify)
                            {
                                ControlMessages controlM = ControlMessages.getInstance();
                                MessageBox.Show(controlM.getMessage(ControlMessages.Msg.InfoExportedInvoice), controlM.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                            }

                        }
                        else
                        {
                            throw new Exception();
                        }
                    }
                    
                catch (Exception e) { throw e; }
            }
        }

        /// <summary>
        /// Método que busca un control por su tag y lo devuelve
        /// </summary>
        /// <param name="tag">Parámetro con el tag del control a buscar</param>
        /// <returns>El ContentControl con el tag especificado por parámetro o null si no se encuentra</returns>
        public Microsoft.Office.Interop.Word.ContentControl getControlByTag(ControlList.Tag tag)
        {
            Microsoft.Office.Interop.Word.ContentControl cc = null;
            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in this.Application.ActiveDocument.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToString("g").ToLower()))
                        {
                            cc = item; break;
                        }

                    }
                }
            }
            catch (Exception) { }
            return cc;
        }

        /// <summary>
        /// Método que abre el taskpane
        /// </summary>
        /// <param name="r"></param>
        public void OpenInvoiceTaskPane(Ribbon1 r)
        {
            Language l = Language.getInstance();
            ribbon = r;
            invoicetaskpane = new InvoiceTaskPane();
            taskPane = this.CustomTaskPanes.Add(invoicetaskpane, l.getLabels("lbMyInvoices"));
            taskPane.Width = 370;
            taskPane.Visible = true;

        }

        /// <summary>
        /// Método que elimina el taskane
        /// </summary>
        public void RemoveInvoiceTaskPane()
        {
            this.CustomTaskPanes.Remove(taskPane);
            invoicetaskpane = null;
        }

        /// <summary>
        /// Método que actualiza el contenido del taskpane
        /// </summary>
        public void updateTaskPane() 
        {
            if (invoicetaskpane != null) 
            {
                invoicetaskpane.updateTaskPane();
            }
        
        }

        /// <summary>
        /// Método que cerga una factura
        /// </summary>
        /// <param name="file">Parámetro de tipo string con el path del archivo a cargar</param>
        /// <param name="corrective">Parámetro de tipo bool que indica si es una factura correctiva</param>
        /// <param name="import">Parámetro de tipo bool que indica si es una importación</param>
        /// <param name="saveOptions">Parámetro de tipo bool que indica si se muestra al usuario la opcion de guardar los cambios o no.</param>
        public void LoadInvoice(string file, bool corrective, bool import, bool saveOptions)
        {
            Word.Document activeDoc = null;

            if (!string.IsNullOrEmpty(file))
            {

                try
                { 
                    XmlSerializer serializer = new XmlSerializer(typeof(Facturae));
                    System.IO.StreamReader r = new System.IO.StreamReader(file);
                    Facturae copia = (Facturae)serializer.Deserialize(r);
                    r.Close();



                    if (import)
                    {
                        setTemplateType(copia, corrective,saveOptions);
                    }

                    try
                    {
                        int rowsCount = 0;
                        try
                        {
                            
                            activeDoc = this.Application.ActiveDocument;
                            rowsCount = this.Application.ActiveDocument.Tables[t2].Rows.Count;
                        }
                        catch (Exception) { }

                        if (activeDoc == null || getControlByTag(ControlList.Tag.IH_InvoiceNumber)== null ||rowsCount>3)
                            setTemplateType(copia, corrective,saveOptions);
                            
                        ValueBinder binder = new ValueBinder(copia, this.Application.ActiveDocument, corrective,InvoiceCulture);
                        if (!import)
                        {
                            ControlMessages msg = ControlMessages.getInstance();
                            MessageBox.Show(msg.getMessage(ControlMessages.Msg.InfoImportDataOK), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (import) 
                        {
                            throw ex;
                        }
                        ControlMessages msg = ControlMessages.getInstance();
                        if (ex.Message.Equals(msg.getMessage(ControlMessages.Msg.ErrorNotValidTemplate)) || ex.Message.Equals(msg.getMessage(ControlMessages.Msg.InfoThirdParty)))
                        {
                            try
                            {
                                DialogResult result = MessageBox.Show(ex.Message, msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                                if (result.Equals(DialogResult.Yes))
                                {
                                    setTemplateType(copia, corrective, false);
                                    ValueBinder binder = new ValueBinder(copia, this.Application.ActiveDocument, corrective, InvoiceCulture);
                                }
                            }
                            catch (Exception exs) { throw exs; }
                            }
                        else
                            MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorLoadInvoiceXML), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    }
                    

                }
                catch (Exception ex)
                {
                    if (import)
                    {
                        throw ex;
                    }
                    ControlMessages controlM = ControlMessages.getInstance();
                    MessageBox.Show(controlM.getMessage(ControlMessages.Msg.ErrorSchema), controlM.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
            }
        }

        /// <summary>
        /// Método que carga un plantilla
        /// </summary>
        /// <param name="temp">Parámetro de tipo object con la plantilla</param>
        /// <param name="saveOptions">Parámetro de tipo bool que indica si se muestra al usuario la opcion de guardar los cambios o no.</param>
        public void LoadInvoiceTemplate(object temp, bool saveOptions)
        {
            try
            {
                object template = temp;
                object oMissing = System.Reflection.Missing.Value;
                object doNotSaveChanges;

                if (saveOptions)
                {
                    ControlMessages msg = ControlMessages.getInstance();
                    DialogResult dr = MessageBox.Show(msg.getMessage(ControlMessages.Msg.InfoSaveDialog), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

                    if (dr.Equals(DialogResult.Yes))
                    {
                        doNotSaveChanges = Microsoft.Office.Interop.Word.WdSaveOptions.wdSaveChanges;
                    }
                    else
                    {
                        doNotSaveChanges = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
                        if (dr.Equals(DialogResult.Cancel))
                            throw new Exception();
                        
                    }
                }
                else
                {
                    doNotSaveChanges = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
                }

                try
                {
                    this.Application.ActiveDocument.Close(ref doNotSaveChanges, ref oMissing, ref oMissing);
                }
                catch (Exception j)
                {
                }               
                

                this.Application.Documents.Add(ref template, ref oMissing, ref oMissing, ref oMissing);

            }
            catch (Exception) { }
        }

        /// <summary>
        /// Método que abre un docx.
        /// </summary>
        /// <param name="temp"></param>
        public void OpenDocx(object temp)
        {
            object template = temp;
            object oMissing = System.Reflection.Missing.Value;
            object doNotSaveChanges = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
            
            this.Application.ActiveDocument.Close(ref doNotSaveChanges, ref oMissing, ref oMissing);

            this.Application.Documents.Add(ref template, ref oMissing, ref oMissing, ref oMissing);

        }

        /// <summary>
        /// Método que guarda un registro de una factura en la bitacora 
        /// </summary>
        /// <param name="year">Parámetro de tipo string con el año</param>
        /// <param name="month">Parámetro de tipo string con el mes</param>
        /// <param name="status">Parámetro de tipo string con el estado</param>
        /// <param name="invoice">Parametro de tipo XmlInvoice con los datos de la factura</param>
        public void save(string year, string month, string status, XmlInvoice invoice)
        {
            try
            {
                parser.addNewXmlInvoiceRecord(year, month, status, invoice);
            }
            catch (Exception e)
            {
                ControlMessages controlM = ControlMessages.getInstance();
                MessageBox.Show(controlM.getMessage(e.Message), controlM.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            }
            

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="schemaUrl"></param>
        /// <param name="schemaNamespaceUri"></param>
        /// <param name="schemaAlias"></param>
        public void AttachCustomXmlSchema(string schemaUrl, string schemaNamespaceUri, string schemaAlias)
        {
            try
            {
                object schemaNamespaceUriObj = schemaNamespaceUri;
                object schemaAliasObj = schemaAlias;
                Word.XMLNamespace customXmlNamespace = null;
                try
                {
                    customXmlNamespace = this.Application.XMLNamespaces.get_Item(ref schemaNamespaceUriObj);
                }
                catch { };
                if (customXmlNamespace == null)
                {
                    customXmlNamespace = this.Application.XMLNamespaces.Add(schemaUrl, ref schemaNamespaceUriObj, ref schemaAliasObj, true);
                }
                object documentObj = this.Application.ActiveDocument;
                customXmlNamespace.AttachToDocument(ref documentObj);
            }
            catch (Exception)
            {

            }
        }
        
        /// <summary>
        /// Método que devuelve el valor de un control cuyo tag es el que se pasa por parámetro.
        /// </summary>
        /// <param name="tag">Parámetro de tipo string con el tag del control a buscar</param>
        /// <returns>Un string con el valor del control</returns>
        public string GetControlValue(ControlList.Tag tag)
        {
            string Value = "";
            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in this.Application.ActiveDocument.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToString("g").ToLower()))
                        {

                            Value = item.Range.Text.Trim();
                            break;
                        }

                    }
                }
            }
            catch (Exception) { return Value; }
            return Value;
        }

        /// <summary>
        /// Método que genera la facura
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path de la factura</param>
        /// <param name="paperInvoice">Parámetro de tipo bool que indica si la factura es en papel</param>
        public void generateInvoice(string path,bool paperInvoice)
        {

            try
            {
                FacturaeGenerator generator = new FacturaeGenerator(new Facturae(), this.Application.ActiveDocument,InvoiceCulture,paperInvoice);
                Facturae facturae = generator.getFacturae();
                XmlSerializer serializer = new XmlSerializer(typeof(Facturae));
                System.IO.StreamWriter w = new System.IO.StreamWriter(path);

                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("namespace", "http://www.facturae.es/Facturae/2007/v3.0/Facturae");
                ns.Add("", "http://www.facturae.es/Facturae/2007/v3.1/Facturae");
                ns.Add("namespace2", "http://uri.etsi.org/01903/v1.3.2#");
                ns.Add("namespace3", "http://www.w3.org/2000/09/xmldsig#");

                serializer.Serialize(w, facturae, ns);
                w.Close();


            }
            catch (Exception e)
            {
                throw e;
            }

        }

        /// <summary>
        /// Método que se encarga de firmar la factura
        /// </summary>
        /// <param name="pathDocBeforeSignature">Parámetro de tipo string con el path de antes de firmar</param>
        /// <param name="pathDocAfterSignature">Parámetro de tipo string con el path de despues de firmar</param>
        /// <param name="configuration">Parámetro de tipo ConfigData referenciando a la configuración definida por el usuario</param>
        /// <param name="f">Parámetro de tipo FrmProgressBar referencia a la barra de progreso que se muestra mientras se está generando la factura.</param>
        public void signateInvoice(string pathDocBeforeSignature, string pathDocAfterSignature, ConfigData configuration,FrmProgressBar f)
        {
            try
            {
                string urlTSA = "http://timestamping.edelweb.fr/service/tsp";
                if (configuration != null)
                {
                    urlTSA = configuration.UrlSTServer;
                }
                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = true;
                doc.Load(pathDocBeforeSignature);
                string role = GetControlValue(ControlList.Tag.InvoiceIssuerType);
                XadesSignature xadesSignature = new XadesSignature();
                if (configuration.SignedType.Equals("XADES-XL"))
                {
                    try
                    {
                        xadesSignature.XadesXL(doc, role, urlTSA,Const.APPLICATION);
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.Equals("ErroCRLOCSPNotFound"))
                        {
                            ControlMessages msg = ControlMessages.getInstance();
                            if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErroCRLOCSPNotFound), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            {
                                doc = new XmlDocument();
                                doc.PreserveWhitespace = true;
                                doc.Load(pathDocBeforeSignature);
                                xadesSignature.XadesEpes(doc, role, Const.APPLICATION);
                            }
                            else
                            {
                                throw new Exception("NotSigned");
                            }
                        }
                        else
                        {
                            throw ex;
                        }
                    }

                }
                else
                {
                    xadesSignature.XadesEpes(doc, role, Const.APPLICATION);
                }
              try
                {
                    f.setMessage("Realizando validación ...");
                    xadesSignature.XadesValidation(doc,false);
                    
                }
                catch (Exception e)
                {
                    throw e;
                }
                

                doc.Save(pathDocAfterSignature);


            }
            catch (Exception ex)
            {
                if (!ex.Message.Equals("ErrorCheckSignature") && !ex.Message.Equals("ErrorCertificateNull") && !ex.Message.Equals("NotSigned"))
                {
                    ControlMessages msg = ControlMessages.getInstance();
                    string error = msg.getMessage("ErrorDocNotSigned") + "  -" + msg.getMessage(ex.Message);
                    throw new Exception(error);
                }
                else
                    throw ex;
            }
        }

        /// <summary>
        /// Método que bloquea todos los controles del documento.
        /// </summary>
        public void ProtectDocument()
        {
            if (document == null)
                document = this.Application.ActiveDocument;


            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in document.ContentControls)
                {
                    item.LockContentControl = true;
                    item.LockContents = true;
                }


            }
            catch (Exception) { }

        }

        /// <summary>
        /// Método que carga los datos del emisor
        /// </summary>
        /// <param name="configData">Parámetro de tipo ConfigData referenciando a la configuración definida por el usuario</param>
        public void LoadIssuerData(ConfigData configData)
        {

            try
            {


                setControlValue(ControlList.Tag.SP_PersonTypeCode, configData.PersonType);
                if (configData.PersonTypeCode.Equals("J"))
                {
                    setControlValue(ControlList.Tag.SP_CorporateName, configData.CompanyName);
                }
                else
                {
                    setControlValue(ControlList.Tag.SP_Name, configData.Name);
                    setControlValue(ControlList.Tag.SP_FirstSurname, configData.FirstName);
                    setControlValue(ControlList.Tag.SP_SecondSurname, configData.SecondName);
                }
                setControlValue(ControlList.Tag.SP_ResidenceTypeCode, configData.ResidenceType);
                setControlValue(ControlList.Tag.SP_TaxIdentificationNumber, configData.CIF);
                setControlValue(ControlList.Tag.SP_CountryCode, configData.Country);
                setControlValue(ControlList.Tag.SP_Province, configData.State);
                setControlValue(ControlList.Tag.SP_Address, configData.Address);
                setControlValue(ControlList.Tag.SP_Telephone, configData.Telephone);
                setControlValue(ControlList.Tag.SP_PostCode, configData.CP);
                setControlValue(ControlList.Tag.SP_Town, configData.County);
                setControlValue(ControlList.Tag.SP_email, configData.Email);


            }
            catch (Exception) { }



        }

        

        /// <summary>
        /// Método que asigna al control cuyo tag se recibe por parámetro el valor que se recibe por parámetro
        /// </summary>
        /// <param name="tag">Parámetro con el tag del control a asignar el valor</param>
        /// <param name="value">Parámetro de tipo string con el valor</param>
        public void setControlValue(ControlList.Tag tag, string value)
        {

            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in this.Application.ActiveDocument.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToString("g").ToLower()))
                        {
                            item.Range.Text = value;
                            break;
                        }

                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Método que realiza una validacion de firma de un archivo cuyo path lo
        /// recibe por parámetro.
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path del archivo a validar</param>
        public void SignatureValidations(string path)
        {

            try
            {
                XmlDocument signedDoc = new XmlDocument();
                signedDoc.PreserveWhitespace = true;
                signedDoc.Load(path);

                XadesSignature xadesSignature = new XadesSignature();
                xadesSignature.XadesValidation(signedDoc,false);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que realiza una validacion contable de un archivo cuyo path lo
        /// recibe por parámetro.
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path del archivo a validar</param>
        /// <param name="import">Parámetro de tipo bool que indica si es una importación o no</param>
        public void AccountingValidation(string path,bool import)
        {
            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = false;
            doc.Load(path);
            try
            {
                InvoiceValidations.ValidationAccountingV31(doc);
            }
            catch (Exception e)
            {
                if (import) 
                {
                    throw e;
                }
                ControlMessages controlM = ControlMessages.getInstance();
                throw new Exception(controlM.getMessage(e.Message));
            }

        }

        /// <summary>
        /// Método que realiza una validacion completa de una factura.
        /// Al final de la validación se muestra un formulario con los resultados
        /// </summary>
        /// <param name="agregarRecibidas">Parámetro de tipo bool que indica si es una factura recibida o no</param>
        /// <returns>True si es válida y false si no lo es.</returns>
        public bool validateReceivedInvoice(bool agregarRecibidas)
        {
            Office.CustomXMLPart customPartReceived;
            ControlMessages msg = ControlMessages.getInstance();

            string infoSchema = msg.getMessage(ControlMessages.Msg.MsgInfoSchema);
            string infoAccount = msg.getMessage(ControlMessages.Msg.MsgAccountOK);
            string infoSigned = msg.getMessage(ControlMessages.Msg.MsgSignedOK);
            string infoSignedType = msg.getMessage(ControlMessages.Msg.MsgInfoSignedType);
            string infoIssue = msg.getMessage(ControlMessages.Msg.MsgInfoIssued);
            string infoSubject = msg.getMessage(ControlMessages.Msg.MsgInfoSubject);
            string infoCertificateStatus = msg.getMessage(ControlMessages.Msg.MsgInfoCertificateStatus);
            string desconocido = msg.getMessage(ControlMessages.Msg.MsgUnknown);
            string OCSP=string.Empty;
            string statusOCSP = string.Empty;
            bool isEpes = false;


            FrmValidation f = new FrmValidation();
            try
            {
                object index = 1;
                string customPartID = GetControlValue(ControlList.Tag.customPartId);

                if (customPartID == null)
                {
                    ControlMessages controlM = ControlMessages.getInstance();
                    throw new Exception(controlM.getMessage(ControlMessages.Msg.ErrorNoCustomPartFound));
                }
                else
                {
                    customPartReceived = this.Application.ActiveDocument.CustomXMLParts.SelectByID(customPartID);

                    if (customPartReceived == null)
                    {
                        string temporalExportPath = Path.GetTempFileName();
                        XmlDocument doc = new XmlDocument();
                        doc.PreserveWhitespace = true;

                        try
                        {      
                            exportPaperInvoice(temporalExportPath, false);
                            doc.Load(temporalExportPath);                            
                        }

                        catch (Exception)
                        {
                            if (agregarRecibidas)
                            {
                                if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                                {
                                    return false;
                                }
                            }
                            f.setImages(false, false, false, msg.getMessage(ControlMessages.Msg.MsgSchemaV31MalFormat), msg.getMessage(ControlMessages.Msg.MsgNoAccountValidation), "", msg.getMessage(ControlMessages.Msg.MsfNoSignedValidation), "", infoSignedType + desconocido, infoIssue + desconocido, infoSubject + desconocido, infoCertificateStatus + desconocido, null, null, desconocido, desconocido,false,false);
                            f.ShowDialog();
                            return false;
                        }

                        try
                        {
                            InvoiceValidations.ValidationAccountingV31(doc);
                            if (!agregarRecibidas)
                            {
                                f.setImages(true, true, false, infoSchema, infoAccount, "", msg.getMessage(ControlMessages.Msg.MsgErrorSignedValidation), msg.getMessage(ControlMessages.Msg.ErrorInvoiceNotSignated), infoSignedType, infoIssue, infoSubject, infoCertificateStatus + desconocido, doc, null, OCSP, statusOCSP, false, false);
                                f.ShowDialog();
                            }
                            return true; 
                        }
                        catch (Exception ex)
                        {
                            if (agregarRecibidas)
                            {
                                if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionRibbon), MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.No)
                                {
                                    return false;
                                }
                            }
                            f.setImages(true, false, false, infoSchema, msg.getMessage(ControlMessages.Msg.MsgErrorAccountValidation), ex.Message, msg.getMessage(ControlMessages.Msg.MsfNoSignedValidation), "", infoSignedType + desconocido, infoIssue + desconocido, infoSubject + desconocido, infoCertificateStatus + desconocido, null, null, desconocido, desconocido,false,false);
                            f.ShowDialog();
                            return false;                            
                        }
                       

                    }
                    else
                    {
                        XmlDocument doc = new XmlDocument();
                        doc.PreserveWhitespace = true;
                        doc.LoadXml(customPartReceived.DocumentElement.XML);
                        XmlDocument docFirmado = new XmlDocument();
                        docFirmado.PreserveWhitespace = true;
                        docFirmado.LoadXml(customPartReceived.DocumentElement.XML);

                        XmlNode signatureNode = doc.DocumentElement.GetElementsByTagName("Signature").Item(0);
                        if (signatureNode == null)
                            signatureNode = doc.DocumentElement.GetElementsByTagName("ds:Signature").Item(0);
                        if (signatureNode != null)
                        {
                            doc.DocumentElement.RemoveChild(signatureNode);
                        }

                        doc.Save(EnvironmentVariable + Paths.InvoiceExtractPath);

                        try
                        {
                            if (System.IO.File.Exists(EnvironmentVariable + Paths.InvoiceExtractPath))
                            {
                                XmlSerializer serializer = new XmlSerializer(typeof(Facturae));
                                System.IO.StreamReader r = new System.IO.StreamReader(EnvironmentVariable + Paths.InvoiceExtractPath);
                                Facturae copia = (Facturae)serializer.Deserialize(r);
                                r.Close();
                            }
                        }
                        catch (Exception)
                        {
                            if (agregarRecibidas)
                            {
                                if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                                {
                                    return false;
                                }
                            }
                            f.setImages(false, false, false, msg.getMessage(ControlMessages.Msg.MsgSchemaV31MalFormat), msg.getMessage(ControlMessages.Msg.MsgNoAccountValidation), "", msg.getMessage(ControlMessages.Msg.MsfNoSignedValidation), "", infoSignedType + desconocido, infoIssue + desconocido, infoSubject + desconocido, infoCertificateStatus + desconocido, null, null, desconocido, desconocido,true,true);
                            f.ShowDialog();
                            return false;
                        }

                        try
                        {
                            InvoiceValidations.ValidationAccountingV31(doc);
                        }
                        catch (Exception ex)
                        {
                            if (agregarRecibidas)
                            {
                                if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                                {
                                    return false;
                                }
                            }
                            f.setImages(true, false, false, infoSchema, msg.getMessage(ControlMessages.Msg.MsgErrorAccountValidation), ex.Message, msg.getMessage(ControlMessages.Msg.MsfNoSignedValidation), "", infoSignedType + desconocido, infoIssue + desconocido, infoSubject + desconocido, infoCertificateStatus + desconocido, null, null, desconocido, desconocido,true,true);
                            f.ShowDialog();
                            return false;
                        }
                        XadesSignature xadesSignature = new XadesSignature();
                        try
                        {

                            xadesSignature.XadesValidation(docFirmado,false);
                            try
                            {
                                string tipoFimra = "";
                                tipoFimra = xadesSignature.ObtenerTipoFirma(docFirmado);
                                if (tipoFimra.Equals("XADES-EPES"))
                                    isEpes = true;
                                else if (tipoFimra.Equals("XADES-XL"))
                                {
                                    isEpes = false;
                                }
                                infoSignedType += tipoFimra;
                            }
                            catch (Exception)
                            {
                                infoSignedType += desconocido;
                            }
                            try
                            {
                                infoIssue += xadesSignature.ObtenerDatosEmisor(docFirmado);
                            }
                            catch (Exception)
                            {
                                infoIssue += desconocido;
                            }
                            try
                            {
                                infoSubject += xadesSignature.ObtenerDatosFirmante(docFirmado);
                            }
                            catch (Exception)
                            {
                                infoSubject += desconocido;
                            }
                            try
                            {
                                OCSP = xadesSignature.obtenerOCSP(docFirmado);
                            }
                            catch (Exception)
                            {
                                OCSP += desconocido;
                            }
                            try
                            {
                                statusOCSP = xadesSignature.obtenerEstadoOCSP(docFirmado, OCSP);
                            }
                            catch (Exception)
                            {
                                statusOCSP += desconocido;
                            }
                        }
                        catch (Exception e)
                        {
                            if (agregarRecibidas)
                            {
                                if (MessageBox.Show(msg.getMessage(ControlMessages.Msg.ErrorAddToReceived), msg.getMessage(ControlMessages.Msg.CaptionRibbon), MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.No)
                                {
                                    return false;
                                }
                            }
                            try
                            {
                                string tipoFimra = "";
                                tipoFimra = xadesSignature.ObtenerTipoFirma(docFirmado);
                                if (tipoFimra.Equals("XADES-EPES"))
                                    isEpes = true;
                                else if (tipoFimra.Equals("XADES-XL"))
                                {
                                    isEpes = false;
                                }
                                infoSignedType += tipoFimra;
                            }
                            catch (Exception)
                            {
                                infoSignedType += desconocido;
                            }
                            try
                            {
                                infoIssue += xadesSignature.ObtenerDatosEmisor(docFirmado);
                            }
                            catch (Exception)
                            {
                                infoIssue += desconocido;
                            }
                            try
                            {
                                infoSubject += xadesSignature.ObtenerDatosFirmante(docFirmado);
                            }
                            catch (Exception)
                            {
                                infoSubject += desconocido;
                            }
                            try
                            {
                                OCSP = xadesSignature.obtenerOCSP(docFirmado);
                            }
                            catch (Exception)
                            {
                                OCSP += desconocido;
                            }
                            try
                            {
                                statusOCSP = xadesSignature.obtenerEstadoOCSP(docFirmado, OCSP);
                            }
                            catch (Exception)
                            {
                                statusOCSP += desconocido;
                            }
                            f.setImages(true, true, false, infoSchema, infoAccount, "", msg.getMessage(ControlMessages.Msg.MsgErrorSignedValidation), msg.getMessage(e.Message), infoSignedType, infoIssue, infoSubject, infoCertificateStatus + desconocido, docFirmado, xadesSignature.obtenerTimeStampToken(docFirmado), OCSP, statusOCSP,true,isEpes);
                            f.ShowDialog();
                            return false;
                        }
                        if (!agregarRecibidas)
                        {
                            f.setImages(true, true, true, infoSchema, infoAccount, "", infoSigned, "", infoSignedType, infoIssue, infoSubject, infoCertificateStatus, docFirmado, xadesSignature.obtenerTimeStampToken(docFirmado), OCSP, statusOCSP,true,isEpes);
                            f.ShowDialog();
                        }
                        return true;
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Método que actualiza los checkbox de estado
        /// </summary>
        /// <param name="ckBoxIssued">Parámetro de tipo bool con el valor del check de emitida</param>
        /// <param name="ckBoxReceived">Parámetro de tipo bool con el valor del check de recibida</param>
        /// <param name="ckBoxDraft">Parámetro de tipo bool con el valor del check de borraror</param>
        /// <param name="status">Parámetro de tipo string con el valor del estado</param>
        public void updateStatusCheck(bool ckBoxIssued, bool ckBoxReceived, bool ckBoxDraft, string status)
        {
            ribbon.getCkBoxIssued().Checked = ckBoxIssued;
            ribbon.getCkBoxReceived().Checked = ckBoxReceived;
            ribbon.getCkBoxDraft().Checked = ckBoxDraft;
            ribbon.setStatus(status);
        }

        /// <summary>
        /// Método que se encarga de emitir una factura
        /// Primero la genera, luego valida la contabilidad y finalmente la firma y valida.
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path de la factura</param>
        /// <param name="pathSignate">Parámetro de tipo string con el path de la firma</param>
        /// <param name="configuration">Parámetro de tipo ConfigData referenciando a la configuración definida por el usuario</param>
        public void emitirFactura(string path, string pathSignate, ConfigData configuration)
        {
            ControlMessages msg = ControlMessages.getInstance();
            FrmProgressBar f = new FrmProgressBar();
            try
            {
                f.Show();
                f.setMessage(msg.getMessage("GeneratedSchema"));
                generateInvoice(path, false);
                f.setMessage(msg.getMessage("AccountValidation"));
                AccountingValidation(path, false);
                f.setMessage(msg.getMessage("Signed"));
                signateInvoice(path, pathSignate, configuration, f);
                f.Close();
            }

            catch (Exception e)
            {
                f.Close();
                throw e;
            }

        }

        /// <summary>
        /// Método igual que el de emitir pero sin firmar.
        /// </summary>
        /// <param name="path">Parámetro de tipo string con el path de la factura</param>
        /// <param name="configuration">Parámetro de tipo ConfigData referenciando a la configuración definida por el usuario</param>
        public void cerrarFactura(string path, ConfigData configuration)
        {
            try
            {
                generateInvoice(path,true);

                AccountingValidation(path,false);
                
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        
        /// <summary>
        /// Método que carga la configuración predeterminada por el usuario de un archivo xml
        /// </summary>
        /// <returns>La configuración</returns>
        public ConfigData LoadConfiguration()
        {
            //Si no se ha cargado la configuración
            if (configuration == null)
            {
                //Creo una nueva
                configuration = new ConfigData();
                //Si no se puede cargar la configuración
                if (!(XmlFile.LoadObjectFrom(ref configuration, EnvironmentVariable + Paths.ConfigPath)))
                {
                    //Pido al usuario si kiere configurarla o si no se creara uno en blanco
                    ControlMessages msg = ControlMessages.getInstance();
                    //Si si kiere le muestro el formulario de configuracion
                    if (MessageBox.Show(String.Concat(msg.getMessage(ControlMessages.Msg.ErrorLoadConfig), "\n", msg.getMessage(ControlMessages.Msg.InfoConfigModifyOrEmpty), "\n", msg.getMessage(ControlMessages.Msg.InfoConfigQuestion)), msg.getMessage(ControlMessages.Msg.CaptionConfig), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        //XmlFile.Save(config, pathConfig, config.GetType());
                        FrmSettings frmSettings = new FrmSettings();
                        frmSettings.Configuration = configuration;
                        frmSettings.Show();
                    }
                    //Sino creo uno en blanco
                    else
                    {
                        XmlFile.Save(configuration, EnvironmentVariable + Paths.ConfigPath, configuration.GetType());
                    }
                }
            }

            return configuration;
        }
               
        /// <summary>
        /// Método que cargar el combobox de los paises.
        /// </summary>
        public void LoadCountryComboBox()
        {

          string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\InformationFiles\" + language + @"\Countries.txt";

            string[] data = { "Afganistán", "AFG", "Albania", "ALB", "Alemania", "DEU", "Andorra", "AND", "Angola", "AGO", "Anguilla", "AIA", "Antigua y Barbuda", "ATG", "Antillas Holandesas", "ANT", "Arabia Saudí", "SAU", "Argelia", "DZA", "Argentina", "ARG", "Armenia", "ARM", "Aruba", "ABW", "ARY Macedonia", "MKD", "Australia", "AUS", "Austria", "AUT", "Azerbaiyán", "AZE", "Bahamas", "BHS", "Bahréin", "BHR", "Bangladesh", "BGD", "Barbados", "BRB", "Bélgica", "BEL", "Belice", "BLZ", "Benin", "BEN", "Bermudas", "BMU", "Bhután", "BTN", "Bielorrusia", "BLR", "Bolivia", "BOL", "Bosnia y Herzegovina", "BIH", "Botsuana", "BWA", "Brasil", "BRA", "Brunéi", "BRN", "Bulgaria", "BGR", "Burkina Faso", "BFA", "Burundi", "BDI", "Cabo Verde", "CPV", "Camboya", "KHM", "Camerún", "CMR", "Canadá", "CAN", "Chad", "TCD", "Chile", "CHL", "China", "CHN", "Chipre", "CYP", "Ciudad del Vaticano", "VAT", "Colombia", "COL", "Comoras", "COM", "Congo", "COG", "Corea del Norte", "PRK", "Corea del Sur", "KOR", "Costa de Marfil", "CIV", "Costa Rica", "CRI", "Croacia", "HRV", "Cuba", "CUB", "Dinamarca", "DNK", "Dominica", "DMA", "Ecuador", "ECU", "Egipto", "EGY", "El Salvador", "SLV", "Emiratos Árabes Unidos", "ARE", "Eritrea", "ERI", "Eslovaquia", "SVK", "Eslovenia", "SVN", "España", "ESP", "Estados Unidos", "USA", "Estonia", "EST", "Etiopía", "ETH", "Filipinas", "PHL", "Finlandia", "FIN", "Fiyi", "FJI", "Francia", "FRA", "Gabón", "GAB", "Gambia", "GMB", "Georgia", "GEO", "Ghana", "GHA", "Gibraltar", "GIB", "Granada", "GRD", "Grecia", "GRC", "Groenlandia", "GRL", "Guadalupe", "GLP", "Guam", "GUM", "Guatemala", "GTM", "Guayana Francesa", "GUF", "Guernsey", "GGY", "Guinea", "GIN", "Guinea Ecuatorial", "GNQ", "Guinea-Bissau", "GNB", "Guyana", "GUY", "Haití", "HTI", "Honduras", "HND", "Hong Kong", "HKG", "Hungría", "HUN", "India", "IND", "Indonesia", "IDN", "Irán", "IRN", "Iraq", "IRQ", "Irlanda", "IRL", "Isla de Man", "IMN", "Isla Norfolk", "NFK", "Islandia", "ISL", "Islas Caimán", "CYM", "Islas Cook", "COK", "Islas Feroe", "FRO", "Islas Malvinas", "FLK", "Islas Marianas del Norte", "MNP", "Islas Marshall", "MHL", "Islas Pitcairn", "PCN", "Islas Salomón", "SLB", "Islas Turcas y Caicos", "TCA", "Islas Vírgenes Británicas", "VGB", "Islas Vírgenes de los Estados Unidos", "VIR", "Israel", "ISR", "Italia", "ITA", "Jamaica", "JAM", "Japón", "JPN", "Jersey", "JEY", "Jordania", "JOR", "Kazajstán", "KAZ", "Kenia", "KEN", "Kirguistán", "KGZ", "Kiribati", "KIR", "Kuwait", "KWT", "Laos", "LAO", "Lesotho", "LSO", "Letonia", "LVA", "Líbano", "LBN", "Liberia", "LBR", "Libia", "LBY", "Liechtenstein", "LIE", "Lituania", "LTU", "Luxemburgo", "LUX", "Macao", "MAC", "Madagascar", "MDG", "Malasia", "MYS", "Malawi", "MWI", "Maldivas", "MDV", "Malí", "MLI", "Malta", "MLT", "Marruecos", "MAR", "Martinica", "MTQ", "Mauricio", "MUS", "Mauritania", "MRT", "Mayotte", "MYT", "México", "MEX", "Micronesia", "FSM", "Moldavia", "MDA", "Mónaco", "MCO", "Mongolia", "MNG", "Montenegro", "MNE", "Montserrat", "MSR", "Mozambique", "MOZ", "Myanmar", "MMR", "Namibia", "NAM", "Nauru", "NRU", "Nepal", "NPL", "Nicaragua", "NIC", "Níger", "NER", "Nigeria", "NGA", "Niue", "NIU", "Noruega", "NOR", "Nueva Caledonia", "NCL", "Nueva Zelanda", "NZL", "Omán", "OMN", "Países Bajos", "NLD", "Pakistán", "PAK", "Palau", "PLW", "Palestina", "PSE", "Panamá", "PAN", "Papúa Nueva Guinea", "PNG", "Paraguay", "PRY", "Perú", "PER", "Polinesia Francesa", "PYF", "Polonia", "POL", "Portugal", "PRT", "Puerto Rico", "PRI", "Qatar", "QAT", "Reino Unido", "GBR", "República Centroafricana", "CAF", "República Checa", "CZE", "República Democrática del Congo", "COD", "República Dominicana", "DOM", "Reunión", "REU", "Ruanda", "RWA", "Rumania", "ROU", "Rusia", "RUS", "Sahara Occidental", "ESH", "Samoa", "WSM", "Samoa Americana", "ASM", "San Cristóbal y Nevis", "KNA", "San Marino", "SMR", "San Pedro y Miquelón", "SPM", "San Vicente y las Granadinas", "VCT", "Santa Helena", "SHN", "Santa Lucía", "LCA", "Santo Tomé y Príncipe", "STP", "Senegal", "SEN", "Serbia", "SRB", "Seychelles", "SYC", "Sierra Leona", "SLE", "Singapur", "SGP", "Siria", "SYR", "Somalia", "SOM", "Sri Lanka", "LKA", "Suazilandia", "SWZ", "Sudáfrica", "ZAF", "Sudán", "SDN", "Suecia", "SWE", "Suiza", "CHE", "Surinam", "SUR", "Svalbard y Jan Mayen", "SJM", "Tailandia", "THA", "Taiwán", "TWN", "Tanzania", "TZA", "Tayikistán", "TJK", "Timor Oriental", "TLS", "Togo", "TGO", "Tokelau", "TKL", "Tonga", "TON", "Trinidad y Tobago", "TTO", "Túnez", "TUN", "Turkmenistán", "TKM", "Turquía", "TUR", "Tuvalu", "TUV", "Ucrania", "UKR", "Uganda", "UGA", "Uruguay", "URY", "Uzbekistán", "UZB", "Vanuatu", "VUT", "Venezuela", "VEN", "Vietnam", "VNM", "Wallis y Futuna", "WLF", "Yemen", "YEM", "Yibuti", "DJI", "Zaire", "ZAR", "Zambia", "ZMB", "Zimbabue", "ZWE" };

            string datos = ReadFile(path);

            if (!string.IsNullOrEmpty(datos))
            {
                data = datos.Replace("\r\n", "").Trim().Split(',');
            }

            try
            {
                int index = 0;

                getControlByTag(ControlList.Tag.SP_CountryCode).DropdownListEntries.Clear();
                getControlByTag(ControlList.Tag.BP_CountryCode).DropdownListEntries.Clear();

                for (int i = 0; i < data.Length; i++)
                {
                    getControlByTag(ControlList.Tag.SP_CountryCode).DropdownListEntries.Add(data[i], data[i + 1], index);
                    getControlByTag(ControlList.Tag.BP_CountryCode).DropdownListEntries.Add(data[i], data[i + 1], index);

                    i++; index++;
                }


            }
            catch (Exception) { }

            try
            {

                int index = 0;

                getControlByTag(ControlList.Tag.TH_CountryCode).DropdownListEntries.Clear();

                for (int i = 0; i < data.Length; i++)
                {
                    getControlByTag(ControlList.Tag.TH_CountryCode).DropdownListEntries.Add(data[i], data[i + 1], index);
                    i++; index++;
                }

            }
            catch (Exception)
            {

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="facturae"></param>
        /// <param name="corrective"></param>
        /// <param name="saveOptions"></param>
        public void setTemplateType(Facturae facturae, bool corrective, bool saveOptions)
        {
            try
            {

                string invoiceIssuer = facturae.FileHeader.InvoiceIssuerType.ToString("g");
                string invoiceClass = facturae.Invoices[0].InvoiceHeader.InvoiceClass.ToString("g");
                string template = EnvironmentVariable + Paths.TemplatePath + TemplatesDirectories;

                if (invoiceIssuer.ToUpper().Equals("TE"))
                {
                    if (invoiceClass.ToUpper().Equals("OR")|| corrective)
                        template += "Rectificativa_por_tercero.dotx";
                    else

                        template += "Emitida_por_Tercero.dotx";
                }
                else
                {
                    if (invoiceClass.ToUpper().Equals("OR")||corrective)
                        template += "RectificativaBasica.dotx";
                    else
                        template += "FacturaeBasica.dotx";

                }

                object temp = template;
                LoadInvoiceTemplate(temp,saveOptions);

            }
            catch (Exception) { }

        }

        /// <summary>
        /// 
        /// </summary>
        public void enumerateTables()
        {
            try
            {
                Word.Document activeDoc = null;
                activeDoc = Globals.ThisAddIn.Application.ActiveDocument;

                if (activeDoc != null)
                {


                    int count = activeDoc.Tables.Count;
                    if (count <= 0)
                    {
                        ControlMessages msg = ControlMessages.getInstance();
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorNotValidTemplate));
                    }
                    else
                    {

                        for (int i = 2; i <= activeDoc.Tables.Count; i++)
                        {
                            try
                            {
                                string table = activeDoc.Tables[i].Rows[1].Cells[1].Range.Text.Trim(x).Trim();
                                t1 = 1;
                                switch (table)
                                {

                                    case "2":
                                        t2 = i; break;
                                    case "3":
                                        t3 = i; break;
                                    case "6":
                                        t4 = i; break;
                                    case "4":
                                        t5 = i; break;
                                    case "1":
                                        t6 = i; break;
                                    case "7":
                                        t7 = i; break;

                                }
                            }
                            catch (Exception) { }
                        }
                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Método que exporta una factura en papel
        /// </summary>
        /// <param name="path"></param>
        /// <param name="notify"></param>
        /// <returns></returns>
        public Facturae exportPaperInvoice(string path, bool notify)
        {
            try
            {
                FacturaeGenerator generador = new FacturaeGenerator(new Facturae(), this.Application.ActiveDocument, InvoiceCulture, true);
                Facturae paperInvoice = generador.getFacturae();

                XmlSerializer serializer = new XmlSerializer(typeof(Facturae));
                System.IO.StreamWriter w = new System.IO.StreamWriter(path);

                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("namespace", "http://www.facturae.es/Facturae/2007/v3.0/Facturae");
                ns.Add("", "http://www.facturae.es/Facturae/2007/v3.1/Facturae");
                ns.Add("namespace2", "http://uri.etsi.org/01903/v1.3.2#");
                ns.Add("namespace3", "http://www.w3.org/2000/09/xmldsig#");

                serializer.Serialize(w, paperInvoice, ns);
                w.Close();

                if (notify)
                {
                    ControlMessages controlM = ControlMessages.getInstance();
                    MessageBox.Show(controlM.getMessage(ControlMessages.Msg.InfoExportedInvoice), controlM.getMessage(ControlMessages.Msg.CaptionFacturae), MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                }
                return paperInvoice;
            }
            catch (Exception e)
            {
                return null;
                throw e;

            }
        }

        /// <summary>
        /// Método que actualiza los checkbox de estado
        /// </summary>
        /// <param name="issued">Parámetro de tipo bool con el valor del check de emitida</param>
        /// <param name="received">Parámetro de tipo bool con el valor del check de recibida</param>
        /// <param name="draft">Parámetro de tipo bool con el valor del check de borraror</param>
        public void updateStatus(bool issued, bool received, bool draft)
        {
            this.ribbon.ckBoxIssued.Checked = issued;
            this.ribbon.ckBoxReceived.Checked = received;
            this.ribbon.ckBoxDraft.Checked = draft;
        }


        #endregion

        #region Código generado por VSTO

        /// <summary>
        /// Método necesario para admitir el Diseñador. No se puede modificar
        /// el contenido del método con el editor de código.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        public string ReadFile(string path)
        {
            try
            {
                using (StreamReader sr = new StreamReader(path, Encoding.Default))
                {
                    return sr.ReadToEnd();
                }
            }
            catch (Exception) { return ""; }
        }



        #endregion

       
        
    }
}
